package com.study.langchain4j.service.tools;

import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.Result;
import dev.langchain4j.service.tool.ToolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author xl-9527
 * @since 2025/11/2
 **/
@Service
public class ToolLowLevelService {

    private static final Logger log = LoggerFactory.getLogger(ToolLowLevelService.class);

    @Bean
    public ToolLowLevelAiService getNowDateChatModel(@Qualifier("chatModel") ChatModel chatModel) {
        // 新增工具
        final ToolSpecification toolSpecification = ToolSpecification.builder()
                .description("获取当前日期，默认格式是 yyyy-MM-dd HH:mm:ss")
                .name("get_now_date")
                .parameters(JsonObjectSchema.builder().build())
                .build();

        final ToolExecutor toolExecutor = (request, memoryId) -> {
            log.info("执行工具：arguments {}", request.arguments());
            log.info("执行工具：tool name {}", request.name());
            log.info("执行工具：memory Id {}", memoryId);
            return LocalDateTime.now().toString();
        };

        return AiServices.builder(ToolLowLevelAiService.class)
                .chatModel(chatModel)
                .tools(Map.of(toolSpecification, toolExecutor))
                .build();
    }

    public interface ToolLowLevelAiService {

        Result<String> getNowDate(String userMessage);
    }

    @Service
    public static class ToolLowLevelAiServiceWithManual {

        private final ChatModel chatModel;

        public ToolLowLevelAiServiceWithManual(@Qualifier("chatModel") final ChatModel chatModel) {
            this.chatModel = chatModel;
        }

        public AiMessage getNowDateWithPrompt(final String userMessage) {
            final ChatResponse chatResponse = chatModel.chat(
                    ChatRequest.builder()
                            .messages(UserMessage.from(userMessage))
                            .toolSpecifications(
                                    ToolSpecification.builder()
                                            .name("get_now_date")
                                            .description("获取当前日期，默认格式是 yyyy-MM-dd HH:mm:ss")
                                            .parameters(JsonObjectSchema.builder().build())
                                            .build()
                            )
                            .build()
            );

            final AiMessage aiMessage = chatResponse.aiMessage();
            if (aiMessage.hasToolExecutionRequests()) {
                if (log.isErrorEnabled()) {
                    log.debug("工具执行请求需要被执行：{}", aiMessage.toolExecutionRequests());
                    final List<ToolExecutionRequest> toolExecutionRequests = aiMessage.toolExecutionRequests();
                    for (final ToolExecutionRequest toolExecutionRequest : toolExecutionRequests) {
                        if (log.isDebugEnabled()) {
                            log.debug("工具执行请求开始：{}", toolExecutionRequest.name());
                        }
                        // 开始执行工具
                        final ToolExecutionResultMessage toolMessage = ToolExecutionResultMessage.from(
                                toolExecutionRequest,
                                LocalDateTime.now().toString()
                        );
                        return chatModel.chat(
                                ChatRequest.builder()
                                        .messages(UserMessage.from(userMessage), aiMessage, toolMessage)
                                        .build()
                        ).aiMessage();
                    }
                }
            }
            return aiMessage;
        }
    }
}
